完整範例:http://wcc723.github.io/d3js/2014/10/26/Ironman-30-days-27/
上次提到d3.js有包含許多的layout,但是每種layout都有些結構上的限制,就比如說 Tree Map,這樣的layout就需要巢狀結構的json才可以製作,D3js也有提供巢狀結構的轉換,這邊就來介紹最常用的轉換方式。
這次的資料又是柯P的,他的資料真的很好用...,不過今天不看圖,今天都來看console.log。
首先透過柯P的API,可以抓到以下的資料,在寫這篇文章時,總共有408筆資料,每一筆資料都是獨立的。
我打算將他分類,以Type(支出、收入)、account(帳戶)作為分類。
只要透過d3.js巢狀的函式,就能輕鬆達到剛剛的需求,如下:
kpPath = 'http://api.kptaipei.tw/v1/financial/all'; //KP資料路徑
d3.json(kpPath, function(d){
dataset = d.data;
console.log(dataset, "原始資料"); //顯示原始資料
var nodesByType = d3.nest() //轉換成巢狀架構
.key(function(d) { return d.type; }) //回傳type
.key(function(d) { return d.account; }) //回傳account
.entries(dataset); //輸入的資料
console.log(nodesByType, "基本d3.js巢狀結構轉換")
});
透過這個函式,就能完成最基本的巢狀資料的轉換,比自幹簡單很多吧...,結果會像下面這樣:
剛剛所設定的type會被轉成第一層的key,而account則會被轉成第二層的key,資料責會被轉成value。
還有一些麻煩的事情要處理,就以剛剛介紹的Tree Map為例,他們所需要的Json格式是像下圖這樣,用的是name、children,並不是剛剛的key、value,所以還要再轉換一下。
kpPath = 'http://api.kptaipei.tw/v1/financial/all'
// --- 轉換巢狀結構的key ---
function reSortRoot(root,value_key) {
for (var key in root) {
if (key == "key") {
root.name = root.key;
delete root.key;
}
if (key == "values") {
root.children = [];
for (item in root.values) {
root.children.push(reSortRoot(root.values[item],value_key));
}
delete root.values;
}
if (key == value_key) {
root.value = parseFloat(root[value_key]);
delete root[value_key];
}
}
return root;
}
// --- 轉換巢狀結構的key ---
d3.json(kpPath, function(d){
dataset = d.data;
console.log(dataset, "原始資料")
var nodesByType = d3.nest() //轉換成巢狀架構
.key(function(d) { return d.type; })
.key(function(d) { return d.account; })
.entries(dataset);
console.log(nodesByType, "基本d3.js巢狀結構轉換")
var root = {};
// 將資料命名
root.key = "Data";
root.values = nodesByType;
// 修改資料的的key, children名稱,並且依指定規則套用。
root = reSortRoot(root,"KpData"); //layout用巢狀架構
console.log(root, "layout用巢狀架構")
});
接下來就看到KP的資料都轉成d3.js layout所需的巢狀json,這樣有助於直接套用許多的樣式。